package com.ccteam.admin.utils

import androidx.lifecycle.Observer

/**
 * @author Xiaoc
 * @since 2021/2/18
 *
 * Event事件包装器
 * 由于 [androidx.lifecycle.LiveData] 是黏性事件
 * 当Fragment中对其进行观察后，当Fragment再次处于前台时便会触发观察
 * 此设计不适用于对于UI的一次性事件，例如 错误提示 之类的案例
 * 所以 Event包装器 可以很好解决此类问题，来防止类似于一次性事件的内容重复被观察消费
 * 它内置一个 hasBeenHandled 值，如果被消费了一次，则会返回 null 不会再次进行消费观察
 */
open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // 禁止被外界自行修改

    /**
     * 如果该事件未被消费，则返回真实值
     * 否则返回 null
     * @return T? 真实值或 null
     */
    fun getContentIfNotHandled(): T?{
        return if(hasBeenHandled){
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * 得到具体的真实值
     */
    fun peekContent(): T = content
}

/**
 * 提供一个 EventObserver 观察器
 * 让你可以更方便得进行已经处理的内容
 *
 * 该观察器只有在Event一次性事件没有被处理时，才会调用对应 lambda 表达式，如果已经处理过则不会进行任何操作
 */
class EventObserver<T>(private val onEventUnhandledContent: (T)-> Unit): Observer<Event<T>>{

    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let { value ->
            onEventUnhandledContent(value)
        }
    }

}